package com.mgfireworks.mgplatform.mgadmin.stock;

import cn.hn.java.summer.db.BaseDao;
import cn.hn.java.summer.db.ConditionEntity;
import cn.hn.java.summer.db.multiple.DataSource1;
import cn.hn.java.summer.exception.BusinessException;
import cn.hn.java.summer.exception.SummerException;
import cn.hn.java.summer.utils.DateUtils;
import cn.hn.java.summer.utils.StringUtils;
import com.mgfireworks.mgplatform.mgadmin.constants.BooleanEnum;
import com.mgfireworks.mgplatform.mgadmin.product.model.Product;
import com.mgfireworks.mgplatform.mgadmin.stock.model.BatchStockInit;
import com.mgfireworks.mgplatform.mgadmin.stock.model.Stock;
import com.mgfireworks.mgplatform.mgadmin.stock.model.StockDetail;
import com.mgfireworks.mgplatform.mgadmin.user.model.User;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 
 * @author nap
 * 20161015-10:19:48
 * 产品库存业务类
 */
@Service
public class StockService extends BaseDao<DataSource1>{
	
	/**
	 * 取产品库存列表
	 * @return
	 */
	public List<StockDetail> getProductStocks(Stock p, User user){
		p.setOrgId(user.getOrgId());
		return list("getProductStocks",StockDetail.class,p);
	}


	/**
	 * 取厂家对应品牌所有未初始库存的产品列表
	 * @return
	 */
	public  List<Product> getUnInitStockProducts(Product p, User user){
	    //设置厂家ID
		p.setOrgId(user.getOrgId());
		return list("getUnInitStockProducts",Product.class,p);
	}

	/**
	 * 添加产品库存(库存初始化操作，厂家原始库存)
	 */
	@Transactional(rollbackFor = Exception.class)
	public void batchInitProductStock(BatchStockInit b, User u) throws BusinessException {
	    //取厂家产品库存中记录数
        final int[] rowCount = {getOrgProductStockDayRowCount(u.getOrgId())};
        try {
            /**
             * `stockId`,
             `orgId`,
             `productId`,
             `areaId`,
             `quantity`,
             `price`,
             */
            batchUpdate("addProductInitStock",b.getProductId(),o -> {
                rowCount[0]++;
               return new Object[]{
                       genProductStockId(u.getOrgId(),rowCount[0]),//库存编号
                       u.getOrgId(),
                       o,
                       u.getAreaId(),
                       b.getQuantity(),
                       b.getPrice()
               };
            });
        } catch (SummerException e) {
            throw new BusinessException("初始库存失败！",e);
        }
    }

	/**
	 * 增加产品库存
	 * @param oldStock
	 * @param increaseNum
	 */
	public void increaseProductStock(Stock oldStock, int increaseNum) throws BusinessException {
		//修改库存,增加库存数
		int result= this.update("updateProductStockQuantity",
				ce().set("stockId",oldStock.getStockId())
				.set("quantity",oldStock.getQuantity())
				.set("num",oldStock.getQuantity()+increaseNum)
		);
		if(result!=1){
			throw new  BusinessException("库存更新失败！");
		}
	}

	/**
	 * 减少现有产品库存
	 * @param oldStock 现有库存信息
	 * @param decreaseNum 减少库存数
	 * @throws BusinessException
	 */
	public void decreaseProductStock(Stock oldStock, int decreaseNum) throws BusinessException {
		if(oldStock.getQuantity()<decreaseNum){
			throw new BusinessException("库存不足！");
		}
		//减少库存
		int result=this.update("updateProductStockQuantity",
				ce().set("stockId",oldStock.getStockId()).
						set("num",oldStock.getQuantity()-decreaseNum).
						set("quantity",oldStock.getQuantity())
		);
		if(result!=1){
			throw new  BusinessException("库存更新失败！");
		}
	}

	/**
	 * 添加新的产品库存
	 * @param user
	 * @param stock
	 */
	public Stock addNewProductStock(User user, Stock stock){
		Stock newStock= ObjectUtils.clone(stock);
		newStock.setOrgId(user.getOrgId());
		newStock.setAreaId(user.getAreaId());
		newStock.setOnline(BooleanEnum.TRUE.value());
		//获取库存序号
		Integer rowCount= getOrgProductStockDayRowCount(user.getOrgId())+1;
		//生成库存编号
		newStock.setStockId(genProductStockId(user.getOrgId(),rowCount));
		//新增库存记录
		this.update("addProductStock",newStock);
		return newStock;
	}

    /**
     * 取机构产品库存当天记录数
     * @param orgId
     * @return
     */
    public int getOrgProductStockDayRowCount(int orgId){
        return get("getOrgProductStockDayRowCount", Integer.class,
                orgId, DateUtils.now("yyMMdd"));
    }

    /**
     * 生成产品库存编号
     * 4位机构编号+yyMMdd+4位序号
     * @param orgId
     * @param index
     * @return
     */
    public String genProductStockId(int orgId,int index){
        //4位机构编号+yyMMdd+4位序号
        return StringUtils.leftPad(orgId+"",4,'0')+DateUtils.now("yyMMdd")+StringUtils.leftPad(index+"",4,'0');
    }

	/**
	 * 修改产品库存(厂家修改原始库存)
	 */
	public void editProductStock(Stock p){
		update("editProductStock",p);
	}
	
	/**
	 * 删除产品库存
	 */
	public void delProductStock(String stockId){
		update("delProductStock",ce().set("stockId",stockId));
	}
	
	/**
	 * 取产品库存信息
	 */
	public StockDetail getProductStock(String stockId){
		return get("getProductStocks",StockDetail.class,ce().set("stockId",stockId));
	}

	/**
	 * 取库存信息
	 * @param conditionEntity
	 * @return
	 */
	public Stock getStock(ConditionEntity conditionEntity) throws BusinessException {
		return get("getProductStocks",Stock.class,conditionEntity);
	}

	/**
	 * 上架库存
	 * @param stockId
	 */
	@Transactional(rollbackFor = Exception.class)
	public void onlineStock(User user, String stockId) throws BusinessException {
		//获取库存信息
		Stock oldStock=getStock(ce().set("stockId",stockId));
		if(oldStock.getOnline()==BooleanEnum.TRUE.value()){
			throw  new BusinessException("已上架，无须再操作！");
		}

		//1.生成新的库存记录
		Stock newStock=addNewProductStock(user,oldStock);

		//2.将新生成的库存编号记录在原下架的库存记录nextStockId中
		oldStock.setNextStockId(newStock.getStockId());
		editProductStock(oldStock);
	}

	/**
	 * 下架库存
	 * @param user
	 * @param stockId
	 */
	public void underlineStock(User user, String stockId) throws BusinessException {
		//获取库存信息
		Stock oldStock=getStock(ce().set("stockId",stockId));
		if(oldStock.getOnline()==BooleanEnum.FALSE.value()){
			throw  new BusinessException("已下架，无须再操作！");
		}

		//标识为下架
		oldStock.setOnline(BooleanEnum.FALSE.value());
		editProductStock(oldStock);
	}

	/**
	 * 调价
	 * @param user
	 * @param stockId
	 */
	public void changePrice(User user, String stockId, double price) throws BusinessException {
		//获取库存信息
		Stock oldStock=getStock(ce().set("stockId",stockId));
		if(oldStock.getOnline()==BooleanEnum.TRUE.value()){
			throw  new BusinessException("请先下架再操作！");
		}

		//修改价格
		oldStock.setPrice(price);
		editProductStock(oldStock);
	}
}